/* Check whether a command is an OS command (binary search on the table
 * os_commands of valid OS commands).
 *
 * this is a supplementary routine used in C.Popen and C.Filter.
 */

#include <ctype.h>

static int cmp_cmd (char *, char *);
 
static char *os_commands[] =
{
	"access",	"adfs",		"alphabet",	"alphabets",
	"append",	"audio",	"basic",	"breakclr",
	"breaklist",	"breakset",	"build",	"cat",
	"cdir",		"channelvoice",	"close",	"configure",
	"continue",	"copy",		"count",	"countries",
	"country",	"create",	"debug",	"delete",
	"deskfs",	"dir",		"dump",		"echo",
	"enumdir",	"error",	"eval",		"ex",
	"exec",		"fileinfo",	"fontcat",	"fontlist",
	"fx",		"go",		"gos",		"help",
	"iconsprites",	"if",		"ignore",	"info",
	"initstore",	"key",		"keyboard",	"lcat",
	"lex",		"lib",		"list",		"load",
	"memory",	"memorya",	"memoryi",	"modules",
	"obey",		"opt",		"poduleload",	"podules",
	"podulesave",	"pointer",	"print",	"qsound",
	"quit",		"ram",		"remove",	"rename",
	"rmclear",	"rmensure",	"rmfaster",	"rmkill",
	"rmload",	"rmreinit",	"rmrun",	"rmtidy",
	"rommodules",	"run",		"save",		"schoose",
	"scopy",	"screenload",	"screensave",	"sdelete",
	"set",		"seteval",	"setmacro",	"settype",
	"sflipx",	"sflipy",	"sget",		"shadow",
	"shellcli",	"show",		"showregs",	"shut",
	"shutdown",	"sinfo",	"slist",	"sload",
	"smerge",	"snew",		"sound",	"speaker",
	"spool",	"spoolon",	"srename",	"ssave",
	"stamp",	"status",	"stereo",	"tempo",
	"time",		"tuning",	"tv",		"type",
	"unplug",	"unset",	"up",		"voices",
	"volume",	"wimppalette",	"wimpslot",	"wimptask",
	"wipe"
};

#define NUM_CMDS (sizeof(os_commands) / sizeof(char *))

int _os_cmd (char *cmd)
{
	int low = 0;
	int high = NUM_CMDS - 1;

	while (low <= high)
	{
		int mid = (high + low) / 2;
		int i = cmp_cmd(cmd,os_commands[mid]);

		if (i == 0)
			return 1;
		else if (i < 0)
			high = mid - 1;
		else
			low = mid + 1;
	}

	return 0;
}

static int cmp_cmd (char *cmd, char *name)
{
	while (*name && tolower(*cmd) == *name)
		++name, ++cmd;

	if (*name)
		return (tolower(*cmd) - *name);

	return (*cmd != '\0' && !isspace(*cmd));
}
